package com.cndw.kungfu.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import com.cndw.kungfu.comm.AccessFlag;
import com.cndw.kungfu.comm.tencent.LogFieldType;
import com.cndw.kungfu.comm.tencent.QQDC;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsCost;
import com.cndw.kungfu.config.ConstantsDayIntKey;
import com.cndw.kungfu.config.ConstantsFlag;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsLog;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.domain.Friend;
import com.cndw.kungfu.domain.GoodsMode;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Scene;
import com.cndw.kungfu.domain.Task;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.DataStaticCenter;
import com.cndw.kungfu.model.player.FriendManager;
import com.cndw.kungfu.model.player.PlayerManager;
import com.cndw.kungfu.model.sys.LogServer;
import com.cndw.kungfu.model.task.PlayerTasks;
import com.cndw.kungfu.vo.EventNotice;
import com.cndw.kungfu.vo.FriendVO;
import com.cndw.rpg.annotation.Controller;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.Session;
import com.cndw.rpg.framework.SessionHolder;

/**
 * 玩家好友操作入口
 * 
 * @author fantadust
 * @date 2011-5-14 上午11:29:15
 */
@Controller
public class FriendController {
	@Autowired
	private FriendManager friendManager;
	@Autowired
	private PlayerManager playerManager;

	/**
	 * 加载我的好友
	 * 
	 * @param session
	 * @return 好友分组 我的好友
	 */
	public ResponseMessage loadFriend(Session session) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("groupNames", player.getDataInfo().getGroupNames());
		Collection<Friend> friends = player.getDataInfo().getFriends();
		List<FriendVO> friendVOs = new ArrayList<FriendVO>();
		for (Friend e : friends) {
			friendVOs.add(e.toFriendVO());
		}		
		map.put("blessNum", player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.bless));
		map.put("blessedNum", player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.blessed));
		map.put("friends", friendVOs);
		map.put("signStatus", "");
		map.put("expbox", player.getDataInfo().intDataGet(ConstantsIntKey.expbox));
		map.put("marryId", player.getDataInfo().getMlId());
		
		QQDC.getInstance().logClick(player, LogFieldType.friend);
		return ResponseMessage.getSuccMessage(map);

	}

	/**
	 * 添加好友
	 * 
	 * @param friendId
	 *            未验证传0
	 * @param friendName
	 * @param groupId
	 *            分组id
	 * @return
	 */
	public ResponseMessage addFriend(Session session, long friendId, String friendName, int groupId) {
		long playerId = session.getUid();
		if (friendId == 0){
			friendId = Context.getPlayerServer().getPlayerId(friendName);
		}	
		if (friendId == 0){
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.err.nofriend"));
		}	
		if (friendId == session.getUid()){
			return null;
		}	
		Player player = Context.getPlayerServer().getByPlayerId(playerId);

		if (player.getDataInfo().getFriendIds().contains(friendId)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.err.haveadd"));
		} else if (player.getDataInfo().getFriendIds().size() >= ConstantsConfig.getFriendNumMax()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.add.overflow"));
		}

		Player targetPlayer = Context.getPlayerServer().getByPlayerId(friendId);
		if (targetPlayer == null) {
			return null;
		}

		// 场景检查
		Scene scene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (scene != null &&  scene.isCityWall() && !scene.isCityMain()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.wall.scene"));
		}

		scene = Context.getSceneServer().getSceneById(targetPlayer.getSceneId());
		if (scene != null && scene.isCityWall() && !scene.isCityMain()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.wall.scene"));
		}

		Friend friend = friendManager.addFriend(playerId, friendId, targetPlayer.getPlayerName(), targetPlayer.getVocationId(), groupId);
		if (friend == null){
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.sys"));
		}
		
		
		player.getDataInfo().addFriend(friend);
		
		EventNotice eventNotice = new EventNotice(ConstantsRadio.friend, ConstantsRadio.friendAdded);
		eventNotice.put("eventId", playerId);
		eventNotice.put("eventName", player.getPlayerName());
		eventNotice.put("eventLevel", player.getLevel());
		eventNotice.broadcast(friendId);
		
		if (!targetPlayer.isOnline()) {
			String title = LanguageLib.get("friend.event.title", player.getPlayerName());
			String content = LanguageLib.get("friend.event.content", player.getPlayerName(),player.getPlayerId());
			Context.getMessageServer().recordEvent(friendId, title, content, Constants.eventTypeFriend);			
		}
		Context.getTaskServer().autoRaidioTask(playerId, 1);
		
		Context.getGeneralServer().addTilte(player.getPlayerId(), Constants.titleFriend, 0);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("newFriend", friend.toFriendVO());
		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 添加别名
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage setNickName(Session session, long friendId, String nickName) {
		Friend friend = Context.getPlayerServer().getByPlayerId(session.getUid()).getDataInfo().getFriend(friendId);
		if (friend == null) {
			return null;
		}
		if (nickName != null) {
			int nameLength = nickName.getBytes(Constants.charset).length;
			if (nameLength < ConstantsConfig.getNameLength() || nameLength > ConstantsConfig.getNameLengthMax()) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.setnickname.illegalnamelength"));
			}
		}

		friend.setNickName(nickName);
		friendManager.updateFriend(friend);
		return ResponseMessage.getSuccMessage(friend.toFriendVO());
	}

	/**
	 * 移动分组
	 * 
	 * @param friendId
	 * @param groupId
	 * @return
	 */
	public ResponseMessage setGroupId(Session session, long friendId, int groupId) {
		Friend friend = Context.getPlayerServer().getByPlayerId(session.getUid()).getDataInfo().getFriend(friendId);
		if (friend == null)
			return null;
		friend.setGroupId(groupId);
		friendManager.updateFriend(friend);
		return ResponseMessage.getSuccMessage(friend.toFriendVO());
	}

	/**
	 * 删除好友
	 * 
	 * @param friendId
	 * @return
	 */
	public ResponseMessage delFriend(Session session, long friendId) {
		long playerId = session.getUid();
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getDataInfo().getMlId() > 0 && player.getDataInfo().getMlId() == friendId) {
			return null;
		}
		Friend friend = player.getDataInfo().getFriend(friendId);
		if (friend != null && friend.getIntimacy() > 0 && player.getDataInfo().isGoodsLock()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("player.pass.lockctrl"));
		}
		
		boolean suc = player.getDataInfo().removeFriend(friendId);
		friendManager.deleteFriend(playerId, friendId);
		return ResponseMessage.getSuccMessage(suc);
	}

	/**
	 * 添加分组
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage addGroup(Session session, String newName) {
		if(newName == null){
			return null;
		}
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		String[] groupNames = player.getDataInfo().getGroupNames();
		if (groupNames.length >= ConstantsConfig.getFriendGroupMax()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.addgroup.toomoregroup"));
		}

		for (int i = 0; i < groupNames.length; i++) {
			String currentName = groupNames[i];
			if (currentName.equals(newName)) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.group.exist"));
			}
		}
		int newLength = groupNames.length + 1;
		groupNames = Arrays.copyOf(groupNames, newLength);
		groupNames[newLength - 1] = newName;
		player.getDataInfo().setGroupNames(groupNames);// 同步分组的信息封装在内部
		player.getDataInfo().commitSync();

		return ResponseMessage.getSuccMessage(newLength - 1);
	}

	/**
	 * 删除分组
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage delGroup(Session session, int indexId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		String[] groupNames = player.getDataInfo().getGroupNames();
		if (indexId == 0)
			return null;
		if (indexId > groupNames.length)
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.group.noexist"));
		int newLength = groupNames.length - 1;
		for (int i = indexId; i < newLength; i++) {
			groupNames[i] = groupNames[i + 1];
		}
		groupNames = Arrays.copyOf(groupNames, newLength);
		for (Friend e : player.getDataInfo().getFriends()) {
			if (e.getGroupId() == indexId) {
				e.setGroupId(0);
			} else if (e.getGroupId() > indexId) {
				e.setGroupId(e.getGroupId() - 1);
			}
		}
		player.getDataInfo().setGroupNames(groupNames);
		return loadFriend(session);// 全部重新加载
	}

	/**
	 * 分组重命名
	 * 
	 * @param indexId
	 * @param newName
	 * @return
	 */
	public ResponseMessage renameGroup(Session session, int indexId, String newName) {
		if(newName == null){
			return null;
		}
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		String[] groupNames = player.getDataInfo().getGroupNames();
		if (indexId > groupNames.length)
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.group.noexist"));
		groupNames[indexId] = newName;
		player.getDataInfo().setGroupNames(groupNames);
		return ResponseMessage.getSuccMessage(true);

	}

	/**
	 * 设置签名
	 * 
	 * @param session
	 * @param signStatus
	 * @return
	 */
	public ResponseMessage setSignStatus(Session session, String signStatus) {

		return ResponseMessage.getSuccMessage(true);

	}

	/**
	 * 祝福好友
	 * @param session
	 * @param friendId
	 */
	public ResponseMessage bless(Session session, long friendId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if(player.getDataInfo().getFriend(friendId) == null){
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.args"));
		}
		if(player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.bless) >= ConstantsModel.friendBlessNum){
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.bless.limit"));
		}
		if(!Context.getPlayerServer().isOnline(friendId)){
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.bless.offline"));
		}
		Player friend = Context.getPlayerServer().getByPlayerId(friendId);
		if(friend.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.blessed) >= ConstantsModel.friendBlessNum){
			return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.bless.max"));
		}
		if(player.getDataInfo().getEveryDay().getBlessSet().contains(friendId)){
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.args"));
		}
		player.getDataInfo().getEveryDay().intDataAlter(ConstantsDayIntKey.bless, 1);
		player.getDataInfo().getEveryDay().getBlessSet().add(friendId);
		player.getDataInfo().commitSync();
		friend.getDataInfo().getEveryDay().intDataAlter(ConstantsDayIntKey.blessed, 1);
		friend.getDataInfo().commitSync();
		int asset = 24 * player.getLevel();
		player.alterAsset(asset);
		player.commitSync();
		int fAsset  = 24 * friend.getLevel();
		friend.alterAsset(fAsset);
		friend.commitSync();
		EventNotice fNotice = new EventNotice(ConstantsRadio.friend, ConstantsRadio.friendBlessAsset);
		fNotice.put("addAsset", fAsset);
		fNotice.put("asset", friend.getAsset());
		fNotice.put("name", player.getPlayerName());
		fNotice.put("playerId", player.getPlayerId());
		fNotice.put("ok", friend.getDataInfo().getEveryDay().getBlessSet().contains(player.getPlayerId()));
		
		fNotice.broadcast(friend.getPlayerId());
		if(friend.getDataInfo().getFriend(session.getUid()) == null){
			String msg = LanguageLib.get("friend.bless.content", player.getPlayerName(), fAsset, player.getPlayerId());
			Context.getMessageServer().recordEvent(friend.getPlayerId(), LanguageLib.get("friend.bless.title"), msg, Constants.eventTypeNormal);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("asset", player.getAsset());
		map.put("addAsset", asset);
		return ResponseMessage.getSuccMessage(map);
	}
	/**
	 * 一键寻友
	 * @param session
	 * @return
	 */
	public ResponseMessage randAdd(Session session){
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getLevel() < ConstantsModel.friendCongLevel[1]) {
			PlayerTasks playerTasks = Context.getTaskServer().getPlayerTasks(session.getUid());
			if (playerTasks.isDoing(78) && playerTasks.geTask(78).getStatus() == Task.STATUS_DOING) {
				
			}else {
				if (DataStaticCenter.getLeftFind(session.getUid()) <= 0) {
					return ResponseMessage.ticpErrMsg(LanguageLib.get("friend.randadd.lefttimes"));
				}
				DataStaticCenter.leftFindAlter(session.getUid(), -1);
			}
			
		}
		Set<Long> currentIds = new HashSet<Long>(player.getDataInfo().getFriendIds());
		
		List<Object> objects = new ArrayList<Object>();
		int num = 0;
		for (int i = 0; i < 20; i++) {
			long idFinal = 0 ;
			int times = 0;		
			do {
				idFinal = SessionHolder.getInstance().getRandOnLineId();
				if (idFinal == 0 || idFinal == session.getUid() || currentIds.contains(idFinal) ) {
					idFinal = playerManager.getRatePlayerId();
				}
				times++;
				if (times >= 10) {
					break;
				}
			} while (idFinal ==0 || idFinal == session.getUid() || currentIds.contains(idFinal));
			Player player2 = Context.getPlayerServer().getByPlayerId(idFinal);
			if (player2 != null && player2.getLevel() >= 3  ) {
				num++;
				currentIds.add(idFinal);
				objects.add(new Object[]{idFinal,player2.getPlayerName(),player2.getLevel(),player2.getVocationId()});
				if (num >= 5) {
					break;
				}
			}			
		}
		return ResponseMessage.getSuccMessage(objects);
	}
	
	public ResponseMessage cong(Session session){
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		int expbox = player.getDataInfo().intDataGet(ConstantsIntKey.expbox);
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("expbox", expbox);
		map.put("findTimes",DataStaticCenter.getLeftFind(session.getUid()));
		map.put("expboxMin", ConstantsModel.friendCongExpBox[0]);
		
		return ResponseMessage.getSuccMessage(map);
	}
	
	/**
	 * 祝贺
	 * @param session
	 * @param s
	 * @param level
	 * @return
	 */
	@AccessFlag(ConstantsFlag.friendzh)
	public ResponseMessage congratulate(Session session,long s,int level) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getLevel() >= ConstantsModel.friendCongLevel[1]) {
			return null;
		}
		int friendzf = player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.friendzf);
		boolean got =  friendzf <  ConstantsModel.friendCongMax;
		boolean suc = DataStaticCenter.friendAwardOne(s,session.getUid(),level,0);
		int gotExp = 0;
		if (suc) {
			EventNotice eventNotice = new EventNotice(ConstantsRadio.friend, ConstantsRadio.friendUpgrade);
			eventNotice.put("uid", player.getPlayerId());
			eventNotice.put("uname", player.getPlayerName());
			eventNotice.put("uV", player.getVocationId());
			eventNotice.put("upLevel", level);
			eventNotice.put("o", 1);
			eventNotice.broadcast(s);
		}else if (!suc) {
			return null;
		}
		if (got) {
			gotExp = player.getLevel() * level;
			player.alterExp(gotExp);
			friendzf++;
			player.getDataInfo().getEveryDay().intDataSet(ConstantsDayIntKey.friendzf, friendzf);
		}
		
		LogServer.recordLog(player, ConstantsLog.player,30501, s, level,gotExp);
		
		Map<String, Object>  map = new HashMap<String, Object>();
		map.put("exp", player.getExp());
		map.put("gotExp", gotExp);
		map.put("freeZf", ConstantsModel.friendCongMax - friendzf);
		return ResponseMessage.getSuccMessage(map);
	}
	/**
	 * 回赠
	 * @param session
	 * @param t
	 * @param level
	 * @param type
	 * @return
	 */
	@AccessFlag(ConstantsFlag.friendzh)
	public ResponseMessage rebate(Session session,long t,int level,int type){
		if (type <0 || type >3 ) {
			return null;
		}
		int[] batArr = ConstantsModel.friendCongExp[type];
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getLevel() >= ConstantsModel.friendCongLevel[1]) {
			return null;
		}		
		if (player.getGoldAll() < batArr[0]) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));
		}
		if (type > 0 && !player.getPlayerBoxs().checkBlack()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.player.boxmin", 1));
		}
		boolean suc = DataStaticCenter.friendAwardOne(session.getUid(),t,level,1);
		if (!suc) {
			return null;
		}
		if (batArr[0] > 0) {
			player.alterGoldAll(-batArr[0]);
			LogServer.costEventLog(session.getUid(), batArr[0], ConstantsCost.friendRebate);
		}
		
		
		player.alterExp(batArr[1]);
		int expbox = player.getDataInfo().intDataGet(ConstantsIntKey.expbox);
		int storeExp = NumberProcesser.between(batArr[2], 0, ConstantsModel.friendCongExpBox[1] - expbox);
		expbox += storeExp;
		player.getDataInfo().intDataSet(ConstantsIntKey.expbox, expbox);
		player.commitSync();
		String awardName = null;
		if (type > 0 && player.getPlayerBoxs().checkBlack()) {
			int gotId = NumberProcesser.getRateOne(ConstantsModel.friendCongAward[type]);
			if (gotId > 0) {
				GoodsMode goodsMode = Context.getGoodsServer().getModeById(gotId);
				awardName = goodsMode.getName();
				Context.getGoodsServer().giveGoodsBing(session.getUid(), gotId, 1, 1);
			}
		}
		
		Map<String, Object>  map = new HashMap<String, Object>();
		LogServer.recordLog(player, ConstantsLog.player,30502, t, level,type,batArr[1],storeExp,expbox,awardName);
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		map.put("gotExp", batArr[1]);
		map.put("exp", player.getExp());
		map.put("storeExp", storeExp);
		map.put("expbox", expbox);
		map.put("awardName", awardName);
		return ResponseMessage.getSuccMessage(map);
	}
	/**
	 * 经验葫芦的领取
	 * @param session
	 * @return
	 */
	@AccessFlag(ConstantsFlag.friendzh)
	public ResponseMessage expbox(Session session) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getLevel() < ConstantsModel.friendCongLevel[1]) {
			return null;
		}
		int expBox = player.getDataInfo().intDataGet(ConstantsIntKey.expbox);
		if (expBox ==0) {
			return null;
		}
		expBox = NumberProcesser.between(expBox, ConstantsModel.friendCongExpBox[0], ConstantsModel.friendCongExpBox[1]);
		player.alterExp(expBox);
		player.getDataInfo().intDataRemove(ConstantsIntKey.expbox);
		player.commitSync();
		player.getDataInfo().commitSync();
		
		LogServer.recordLog(player, ConstantsLog.player,30503, expBox);
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("expbox", expBox);
		map.put("exp", player.getExp());
		
		return ResponseMessage.getSuccMessage(map);
	}
	
	
}
